/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.mzk.oai;

import ORG.oclc.oai.server.crosswalk.Crosswalk;
import ORG.oclc.oai.server.verb.CannotDisseminateFormatException;
import cz.mzk.oai.metadataRepository.metadata.MetadataFormat;
import cz.mzk.oai.metadataRepository.repository.collections.Item;
import cz.mzk.oai.metadataRepository.repository.records.NoSuchRecordException;
import cz.mzk.oai.metadataRepository.repository.Repository;
import java.io.IOException;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.dom4j.Document;
import org.dom4j.Element;

/**
 *
 * @author Martin Rehanek, Martin.Rehanek@gmail.com
 */
public abstract class AbstractCrosswalk extends Crosswalk {

    protected Repository repository;
    private MetadataFormat METADATA_FORMAT;

    public AbstractCrosswalk(Properties properties, MetadataFormat format) {
        super((format.getNamespace() + " " + format.getSchemaUrl()));
        METADATA_FORMAT = format;
        repository = Repository.instanceOf(properties);
    }

    public abstract boolean isAvailableFor(Object nativeItem);

    /**
     *
     * @param nativeItem
     * @return String containing the metadata
     * @throws CannotDisseminateFormatException If the record cannot be created for the Crosswalk
     */
    @Override
    public String createMetadata(Object nativeItem) throws CannotDisseminateFormatException {
        try {
            if (!isAvailableFor(nativeItem)) {
                throw new CannotDisseminateFormatException(METADATA_FORMAT.name());
            }
            String id = ((Item) nativeItem).getId();
            boolean validate = false;
            switch (METADATA_FORMAT) {
                case marc21:
                    validate = true;
                    break;
                default:
                    validate = true;
                    break;
            }
            Document doc = repository.getRecord(id, METADATA_FORMAT, validate);
            //remove processing instructions
            Element root = doc.getRootElement();
            return root.asXML();
        } catch (IOException ex) {
            throw new CannotDisseminateFormatException(METADATA_FORMAT.name());
        } catch (NoSuchRecordException ex) {
            throw new CannotDisseminateFormatException(METADATA_FORMAT.name());
        }
    }

    public MetadataFormat getMetadataFormat() {
        return METADATA_FORMAT;
    }
}
